/** \file inmain.c
 *  Test the grammer written, Adapted from Jim Idle which is adpated from Java equivalent
 *  example, by Terence Parr
 * \author Ameen Jaber
 * \author Mohamad Noureddine
 * \author Mohamed Sabra
 */

#include <InData.h>
#include <defs.h>
#include <visit.h>
#include <iostream>
#include <InDataLexer.h>
#include <InDataParser.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <boost/config.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/unordered_map.hpp>

using namespace std;


// Main entry point for this example
//
int ANTLR3_CDECL
main	(int argc, char *argv[])
{
  pANTLR3_UINT8 fName;
  pANTLR3_INPUT_STREAM input;
  pInDataLexer lxr;
  pANTLR3_COMMON_TOKEN_STREAM tstream;
  pInDataParser psr;

  bool dotFile=false;
  bool translate=false;
  string inputFile="";
  string inputState="";
  string outState="";
  int opt;

  while((opt = getopt(argc, argv, "i:dt:o:T"))!= -1){
    switch (opt) {
    case 'i':
      inputFile+=optarg;
      fName=(pANTLR3_UINT8)(inputFile.c_str());
      break;
    case 'd':
      dotFile=true;
      break;
    case 't':
      inputState+=optarg;
      break;
    case 'o':
      outState+=optarg;
      break;
    case 'T':
      translate=true;
      break;
    default:
      fprintf(stderr, "Usage: %s [-i {filename}] [-d generate dot] [-T translate] [-t {Input State}] [-o {Output State}]\n",
	      argv[0]);
      exit(EXIT_FAILURE);

    }
  }

  input	= antlr3AsciiFileStreamNew(fName);
  if ( input == NULL)
    {
      fprintf(stderr, "Failed to open file %s\n", (char *)fName);
      exit(1);
    }
  lxr= InDataLexerNew(input); // CLexerNew is generated by ANTLR

  // Need to check for errors
  //
  if ( lxr == NULL )
    {
      fprintf(stderr, "Unable to create the lexer due to malloc() failure1\n");
      exit(1);
    }
  tstream = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(lxr));

  if (tstream == NULL)
    {
      fprintf(stderr, "Out of memory trying to allocate token stream\n");
      exit(1);
    }

  // Finally, now that we have our lexer constructed, we can create the parser
  //
  psr = InDataParserNew(tstream);  // CParserNew is generated by ANTLR3

  if (psr == NULL)
    {
      fprintf(stderr, "Out of memory trying to allocate parser\n");
      exit(ANTLR3_ERR_NOMEM);
    }

  cout<<"Starting Parsing"<<endl;
  varTable_t * a=psr->translation_unit(psr);
  cout<<"Parsing Ended"<<endl;
 #if 0
  varTable_t::iterator it;
  it = a->find("b");
  pppsequence * b = (pppsequence*)((it)->second);
  std::cout << "B is of size " << b->data->size() << std::endl;
  std::vector<object *>::iterator _it;
  for (_it = b->data->begin() ; _it != b->data->end() ; _it++) {
    //pppsequence * v = (pppsequence*)(*_it);
    std::cout << "Size = " << ((pppsequence*)(*_it))->data->size() << std::endl;
  }
  std::cout << b->data->size();
  pppsequence * subb = (pppsequence*)((*(b->data))[0]);
  std::cout << "---> set b has an internal set having a value " << (*(subb->data))[0]->val << std::endl;
#endif 
  psr	    ->free  (psr);	    psr = NULL;
  tstream ->free  (tstream);	    tstream = NULL;
  lxr	    ->free  (lxr);	    lxr = NULL;
  input   ->close (input);	    input = NULL;

  return 0;
}
